/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package de.bastian.hinterleitner;

import java.util.ArrayList;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import de.bastian.hinterleitner.adaptersviews.BasicAdapter;
import de.bastian.hinterleitner.adaptersviews.CategoryAdapter;
import de.bastian.hinterleitner.adaptersviews.CategorySelectAdapter;
import de.bastian.hinterleitner.adaptersviews.StandardAdapter;
import de.bastian.hinterleitner.database.DataHelper;
import de.bastian.hinterleitner.tools.Category;
import de.bastian.hinterleitner.tools.Constants;
import de.bastian.hinterleitner.tools.DeleteTask;
import de.bastian.hinterleitner.tools.Entry;
import de.bastian.hinterleitner.tools.EntrySorter;
import de.bastian.hinterleitner.tools.WatchYourCashActivity;
import de.hijacksoft.wyc.R;

/**
 * 
 * @author basti
 */
public class Categories extends WatchYourCashActivity implements
		OnItemClickListener, OnItemLongClickListener {

	private ListView list;
	BasicAdapter listAdapter;
	Category category;

	private static final String TAG = "WatchYourCash_Category";

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		if (icicle != null) {
			if(icicle.getString("cat")!=null){
				category = DataHelper.getDataHelper(this).getCategoryByName(icicle.getString("cat"));
			}else{
				category = null;
			}
		}
		setContentView(R.layout.activity_category);
		initGUI();
	}

	@Override
	public void onSaveInstanceState(Bundle savedInstanceState) {
		super.onSaveInstanceState(savedInstanceState);
		if(category != null){
			savedInstanceState.putString("cat", category.name);
		}
	}

	private void initGUI() {
		list = (ListView) findViewById(R.id.category_list);
		refreshList();
		if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
			initHeader(list);
		} else {
			initHeader(list,
					((LinearLayout) findViewById(R.id.category_content)));
		}
		list.setOnItemClickListener(this);
		list.setOnItemLongClickListener(this);
		initNav((LinearLayout) findViewById(R.id.category_header),
				getString(R.string.overview));
		initFooter(((LinearLayout) findViewById(R.id.category_layout_footer)));
		initLeftNavigation(((LinearLayout) findViewById(R.id.main_layout_overlay)));
	}

	private void onIconClicked(int index) {
		final String cat = listAdapter.getItem(index).getName();

		final ViewGroup parent = ((LinearLayout) findViewById(R.id.category_spinners));

		CategorySelectAdapter adapter = new CategorySelectAdapter(this,
				toCategories(Constants.iconNames()));
		final Spinner spinner = new Spinner(this);
		spinner.setAdapter(adapter);
		spinner.setPrompt(getString(R.string.iconselect).replace("$1", cat));
		DataHelper dh = DataHelper.getDataHelper(this);
		final int prior = Constants.iconNames().indexOf(
				dh.getCategoryDrawableName(cat));
		spinner.setSelection(prior);

		parent.addView(spinner);

		spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1, int pos,
					long arg3) {
				if (pos != prior) {
					DataHelper dh = DataHelper.getDataHelper(Categories.this);
					dh.setCategoryDrawable(cat, Constants.iconNames().get(pos));
					parent.removeAllViews();
					refreshList();
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				parent.removeAllViews();
			}
		});

		spinner.performClick();
	}

	private void refreshList() {
		new RefreshTask().execute();
	}

	private void notifyList() {
		listAdapter.entries = EntrySorter.getSingleton(this).sortBy(
				listAdapter.entries, Entry.sorting);
		listAdapter.notifyDataSetChanged();
		notifyHeader();
	}

	private ArrayList<Entry> getItems() {
		DataHelper dh = DataHelper.getDataHelper(this);
		ArrayList<Category> names = dh.getAllCategories();
		ArrayList<Entry> entryList = new ArrayList<Entry>();
		for (Category cat : names) {
			entryList.add(new Entry(cat.name, dh.getValueOfCategory(cat
					), Constants.ID_NODATE));
		}
		return entryList;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == RESULT_OK)
			refreshList();
	}

	@Override
	protected void onNavEntryClicked(Button b) {
		category = null;
		refreshList();
	}

	public void onItemClick(AdapterView<?> av, View view, int i, long l) {
		i--; // because of header-view
		if (listAdapter instanceof CategoryAdapter) {
			String name = listAdapter.getItem(i).getName();
			category = DataHelper.getDataHelper(this).getCategoryByName(name);
			setNavEntry(category.name);
			refreshList();
		} else {
			Intent intent = new Intent(this, NewEntry.class);
			intent.putExtra("itemId", "" + listAdapter.getItem(i).getId());
			startActivityForResult(intent, Constants.REQUEST_EDIT_ITEM);
		}
	}

	public boolean onItemLongClick(AdapterView<?> av, View view, int i, long l) {
		i--; // because of header-view
		if (listAdapter.getItemId(i) != -1) {
			if (category != null) {
				final int id = i;
				question(
						getString(R.string.deletequestion).replace("$1",
								listAdapter.getItem(id).getName()),
						getString(R.string.yes), getString(R.string.no),
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface di, int i) {
								DataHelper d = DataHelper
										.getDataHelper(Categories.this);
								d.delete((int) listAdapter.getItemId(id));
								refreshList();
							}
						}, null);
			} else {
				editCategory(listAdapter.getItem(i).getName());
			}
		}
		return true;
	}

	public class RefreshTask extends
			AsyncTask<Integer, String, ArrayList<Entry>> {

		@Override
		protected void onPreExecute() {
			loading(true);
			setRequestedOrientation(getResources().getConfiguration().orientation);
		}

		@Override
		protected void onProgressUpdate(String... values) {
			setNavEntry(values[0]);
		}

		@Override
		protected ArrayList<Entry> doInBackground(Integer... paramss) {
			if (category == null) {
				ArrayList<Entry> items = getItems();
				items = EntrySorter.getSingleton(Categories.this).sortBy(items,
						Entry.sorting);
				return items;
			} else {
				DataHelper dh = DataHelper.getDataHelper(Categories.this);
				ArrayList<Entry> items = dh.getAllEntriesByCategory(category);
				items = EntrySorter.getSingleton(Categories.this).sortBy(items,
						Entry.sorting);
				return items;
			}
		}

		@Override
		protected void onPostExecute(ArrayList<Entry> result) {
			if (category == null) {
				switchNavBarTo(1);
				ImageButton search = (ImageButton) findViewById(R.id.layout_header_btn_search);
				search.setImageResource(R.drawable.androidadd);
				search.setOnClickListener(new View.OnClickListener() {
					@Override
					public void onClick(View v) {
						addCategory();
					}
				});
				listAdapter = new CategoryAdapter(Categories.this, result) {
					@Override
					public void buttonClicked(int index) {
						onIconClicked(index);
					}
				};
				list.setAdapter(listAdapter);
			} else {
				ImageButton search = (ImageButton) findViewById(R.id.layout_header_btn_search);
				search.setImageResource(R.drawable.androidinfo);
				search.setOnClickListener(new View.OnClickListener() {
					@Override
					public void onClick(View v) {
						startActivity(new Intent(getApplicationContext(),
								WhatsNewActivity.class));
					}
				});
				listAdapter = new StandardAdapter(Categories.this, result);
				list.setAdapter(listAdapter);
			}
			loading(false);
			notifyList();
			list.setSelection(0);
			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
		}

	}

	public class RenameTask extends AsyncTask<String, String, Boolean> {

		ProgressDialog pd;
		String failmsg;

		@Override
		protected void onPreExecute() {
			setRequestedOrientation(getResources().getConfiguration().orientation);
			pd = new ProgressDialog(Categories.this);
			pd.setTitle("");
			pd.setMessage("");
			pd.show();
		}

		@Override
		protected void onProgressUpdate(String... values) {
			if (values.length == 2) {
				pd.setMessage(getString(R.string.deleting).replace("$1",
						values[1]));
			} else {
				pd.setMessage(getString(R.string.renaming).replace("$1",
						values[1]).replace("$2", values[2]));
			}
		}

		@Override
		protected Boolean doInBackground(String... paramss) {
			publishProgress(paramss);
			failmsg = paramss[0];
			boolean fail = false;
			DataHelper dh = DataHelper.getDataHelper(Categories.this);
			if (paramss.length == 2) {
				Category cat = DataHelper.getDataHelper(Categories.this).getCategoryByName(paramss[1]);
				fail = dh.deleteCategory(cat);
			} else {
				Category cat = DataHelper.getDataHelper(Categories.this).getCategoryByName(paramss[1]);
				fail = dh.renameCategory(cat, paramss[2]);
			}
			return fail;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			pd.dismiss();
			if (result) {
				refreshList();
			} else
				dialog(failmsg);
			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
		}

	}

	private void editCategory(final String catName) {

		final AlertDialog alertDialog = new AlertDialog.Builder(this).create();
		alertDialog.setTitle(catName);

		LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View view = inflator.inflate(R.layout.dialog_categoryedit, null);

		alertDialog.setView(view);

		final EditText name = (EditText) view
				.findViewById(R.id.categoryedit_edittext_name);
		name.setText(catName);
		name.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);

		ImageButton delete = (ImageButton) view
				.findViewById(R.id.categoryedit_button_delete);

		// init Spinner
		final Spinner icons = (Spinner) view
				.findViewById(R.id.categoryedit_spinner_icon);
		icons.setPrompt(getString(R.string.iconselect).replace("$1", catName));
		ArrayList<String> categories = Constants.iconNames();
		CategorySelectAdapter adapter = new CategorySelectAdapter(this,
				toCategories(Constants.iconNames()));
		icons.setAdapter(adapter);
		final DataHelper dh = DataHelper.getDataHelper(this);
		final int pos = categories.indexOf(dh.getCategoryDrawableName(catName));
		icons.setSelection(pos);

		delete.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				question(
						getString(R.string.deletecategoryquestion).replace(
								"$1", catName), getString(R.string.yes),
						getString(R.string.no),
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface arg0, int arg1) {
								question(
										getString(R.string.deleteormove),
										getString(R.string.delete),
										getString(R.string.move),
										new DialogInterface.OnClickListener() {
											@Override
											public void onClick(
													DialogInterface dialog,
													int which) {
												dialog.cancel();
												alertDialog.cancel();
												Category cat =  dh.getCategoryByName(catName);
												delete(dh
														.getAllEntriesByCategory(cat),
														catName);
											}
										},
										new DialogInterface.OnClickListener() {
											@Override
											public void onClick(
													DialogInterface dialog,
													int which) {
												dialog.cancel();
												alertDialog.cancel();
												new RenameTask()
														.execute(new String[] {
																getString(R.string.cantdelete),
																catName });
											}
										});
							}
						}, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface arg0, int arg1) {
								arg0.cancel();
							}
						});
			}
		});

		((Button) view.findViewById(R.id.categoryedit_button_ok))
				.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View dialog) {
						if (pos != icons.getSelectedItemPosition()) {
							DataHelper dh = DataHelper
									.getDataHelper(Categories.this);
							String iconName = icons.getSelectedItem()
									.toString();
							dh.setCategoryDrawable(catName, iconName);
							refreshList();
						}
						if (!catName.equals(name.getText().toString())) {
							if (catName
									.equals(getString(R.string.uncategorized))) {
								dialog(getString(R.string.cantdelete));
							} else {
								new RenameTask().execute(new String[] {
										getString(R.string.alreadyexists),
										catName, name.getText().toString() });
							}
						}
						alertDialog.cancel();
					}
				});

		((Button) view.findViewById(R.id.categoryedit_button_cancel))
				.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View dialog) {
						alertDialog.cancel();
					}
				});

		alertDialog.show();
	}

	private void delete(ArrayList<Entry> list, String catName) {
		new DeleteTask(Categories.this, list) {
			@Override
			public void onFinish(boolean success) {
				refreshList();
				if (!success) {
					dialog(getString(R.string.cantdelete));
				}
			}
		}.execute(new String[] { catName });
	}

	private void addCategory() {
		AlertDialog alertDialog = new AlertDialog.Builder(this).create();
		alertDialog.setTitle(getString(R.string.newcategory));

		final EditText name = new EditText(this);
		name.setHint(getString(R.string.name));
		name.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);

		final TextView cat = new TextView(this);
		cat.setText(R.string.icon);
		cat.setTextColor(Color.WHITE);

		CategorySelectAdapter adapter = new CategorySelectAdapter(this,
				toCategories(Constants.iconNames()));
		final Spinner spinner = new Spinner(this);
		spinner.setAdapter(adapter);
		spinner.setPrompt(getString(R.string.iconselectsimple));

		LinearLayout view = new LinearLayout(this);
		view.setOrientation(LinearLayout.VERTICAL);
		view.addView(name);
		view.addView(cat);
		view.addView(spinner);

		alertDialog.setView(view);

		alertDialog.setButton(getString(R.string.ok),
				new android.content.DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						DataHelper dh = DataHelper
								.getDataHelper(Categories.this);
						String icon = Constants.iconNames().get(
								spinner.getSelectedItemPosition());
						Category cat = new Category(name.getText().toString(), icon, -1);
						if (!dh.addCategory(cat)) {
							dialog(getString(R.string.alreadyexists));
						} else {
							category = null;
							refreshList();
						}
					}
				});

		alertDialog.setButton2(getString(R.string.cancel),
				new android.content.DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
					}
				});

		alertDialog.show();
	}

	@Override
	public boolean onCreatePopupMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.layout.menu_optionsmenu, menu);
		return super.onCreatePopupMenu(menu);
	}

	@Override
	public boolean onMenuOpened(int featureId, Menu menu) {
		enableAllOptions(menu);
		try {
			menu.findItem(R.id.sort_by_category).setVisible(false);
			if (category == null)
				menu.findItem(R.id.sort_by_date).setVisible(false);
			else
				menu.findItem(R.id.sort_by_date).setVisible(true);

			if (Entry.sorting == EntrySorter.SORT_BY_NAME)
				menu.findItem(R.id.sort_by_name).setVisible(false);
			if (Entry.sorting == EntrySorter.SORT_BY_AMOUNT)
				menu.findItem(R.id.sort_by_amount).setVisible(false);
			if (Entry.sorting == EntrySorter.SORT_BY_DATE)
				menu.findItem(R.id.sort_by_date).setVisible(false);

		} catch (NullPointerException ex) {
			ex.printStackTrace();
		}
		return super.onMenuOpened(featureId, menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.sort_by_amount:
			Entry.sorting = EntrySorter.SORT_BY_AMOUNT;
			refreshList();
			break;
		case R.id.sort_by_name:
			Entry.sorting = EntrySorter.SORT_BY_NAME;
			refreshList();
			break;
		case R.id.sort_by_date:
			Entry.sorting = EntrySorter.SORT_BY_DATE;
			refreshList();
			break;
		case R.id.sort_by_category:
			Entry.sorting = EntrySorter.SORT_BY_CATEGORY;
			refreshList();
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public boolean hasOptionsMenu() {
		return true;
	}

	private ArrayList<Category> toCategories(ArrayList<String> iconNames) {
		ArrayList<Category> result = new ArrayList<Category>();
		for (int i = 0; i < iconNames.size(); i++) {
			result.add(new Category(iconNames.get(i), iconNames.get(i), -1));
		}
		return result;
	}

}